<template>
  <div ref="flow" style="height: 100vh"></div>
  <Teleport to="body">
    <div class="modal" :style="detailStyle" v-if="detailShow">
      <Detail></Detail>
    </div>
  </Teleport>
</template>
<script setup>
// npm i @logicflow/core
// npm i @logicflow/extension
import { ref, onMounted } from "vue";
import LogicFlow from "@logicflow/core";
import "@logicflow/core/dist/index.css";
import CustomPolygon from "./component/CustomPolygon";
import DetailHtml from "./component/DetailHtml";
import RequestIpHtml from "./component/RequestIpHtml";
import TargetIpHtml from "./component/TargetIpHtml";
import TagHtml from "./component/TagHtml";
import LineEdge from "./component/LineEdge";
import TextHtml from "./component/TextHtml";
import Detail from "./Detail.vue";

const input = {
  sensitiveWords: [
    { name: "ID Card", id: "1,5" },
    { name: "License Plate", id: "2,3" },
    { name: "Phone Number", id: "2,4" },
  ],
  source: [
    {
      name: "测试传值1",
      api: [
        { id: "1", ip: "/api 1" },
        { id: "2", ip: "/api 2" },
        { id: "3", ip: "/api 3" },
        { id: "13", ip: "/api 4" },
        { id: "14", ip: "/api 5" },
      ],
    },
    {
      name: "测试传值2",
      api: [
        { id: "4", ip: "/api 1" },
        { id: "5", ip: "/api 2" },
      ],
    },
  ],
};
const lastClickId = ref("");
const detailShow = ref(false);

const detailStyle = ref({
  top: "0px",
  left: "0px",
});

const flow = ref(null);
// https://site.logic-flow.cn/api/detail/constructor
onMounted(() => {
  const nodes = generateNodes(input);
  const lf = new LogicFlow({
    container: flow.value,
    grid: false,
    textEdit: false,
    adjustNodePosition: false,
  });
  lf.register(CustomPolygon);
  lf.register(DetailHtml);
  lf.register(RequestIpHtml);
  lf.register(TargetIpHtml);
  lf.register(TagHtml);
  lf.register(LineEdge);
  lf.register(TextHtml);
  lf.render({
    nodes: nodes,
    edges: generateEdges(input, nodes),
  });
  lf.on("edge:click", async ({ data, e, position }) => {
    console.log("edge:click", data, e, position);
    detailShow.value = false;
    if (lastClickId.value) {
      await lf.setProperties(lastClickId.value, { type: "" });
    }
    if (!data.id.startsWith("target-ip-tag-")) {
      detailShow.value = true;
      // detailStyle.value.top = e.clientY + 'px'
      // detailStyle.value.left = e.clientX + 'px'
      detailStyle.value.top = position.domOverlayPosition.y + "px";
      detailStyle.value.left = position.domOverlayPosition.x + "px";
      lastClickId.value = data.id;
      await lf.setProperties(data.id, { type: "PASS" });
    }
  });
  lf.on("blank:click", () => {
    detailShow.value = false;
    lf.setProperties(lastClickId.value, { type: "" });
  });
  lf.on("element:click", () => {
    detailShow.value = false;
    lf.setProperties(lastClickId.value, { type: "" });
  });
});

function generateNodes(input) {
  const nodes = [];

  // 固定节点
  nodes.push({
    id: "request-ip",
    type: "RequestIpHtml",
    x: 150,
    y: 150,
    properties: {
      data: {
        text: "测试传值(请求IP)",
      },
    },
  });

  nodes.push({
    id: "target-ip",
    type: "TargetIpHtml",
    x: 500,
    y: 150,
    properties: {
      width: 220,
      height: 180,
      data: {
        text: "测试传值(服务器IP)",
        api: ["/api 1"],
      },
    },
  });

  nodes.push({
    id: "tag-header",
    type: "TextHtml",
    x: 780,
    y: 70,
    properties: {
      text: "Sensitive Keywords",
    },
  });

  // 动态生成敏感字节点
  input.sensitiveWords.forEach((word, index) => {
    nodes.push({
      id: `tag-${index}`,
      type: "TagHtml",
      x: 780,
      y: 140 + index * 80, // 每个 API 增加 80 高度
      properties: {
        data: {
          text: word.name,
        },
      },
    });
  });

  // 动态生成目标服务节点
  let currentY = 60; // 初始 y 坐标
  input.source.forEach((service, index) => {
    const apiCount = service.api.length;
    const height = 180 + (apiCount - 1) * 45; // 每个 API 增加 45 高度
    const centerY = currentY + height / 2; // 计算中心点的 y 坐标

    nodes.push({
      id: `source-${index}`,
      type: "TargetIpHtml",
      x: 1100,
      y: centerY,
      properties: {
        width: 220,
        height: height,
        data: {
          text: service.name,
          api: service.api.map((api) => api.ip),
        },
      },
    });

    // 更新 currentY，加上高度和空隙
    currentY += height + 30; // 每个服务节点之间增加 30 的空隙
  });

  return nodes;
}

function generateEdges(input, nodes) {
  const edges = [];

  edges.push({
    id: "requst-ip-target-ip",
    sourceNodeId: "request-ip",
    targetNodeId: "target-ip",
    type: "ServerLine", // 连接线类型为直线
    // properties: {
    //   type: "PASS",
    // },
    startPoint: {
      x: 260, // 起始点的 x 坐标
      y: 160, // 起始点的 y 坐标
    },
    endPoint: {
      x: 450, // 结束点的 x 坐标
      y: 185, // 结束点的 y 坐标
    },
  });
  // 服务器IP到每个敏感字节点的连接
  input.sensitiveWords.forEach((_, index) => {
    edges.push({
      id: `target-ip-tag-${index}`,
      sourceNodeId: "target-ip",
      targetNodeId: `tag-${index}`,
      type: "ServerLine", // 连接线类型为直线
      startPoint: {
        x: 610, // 起始点的 x 坐标
        y: 160, // 起始点的 y 坐标
      },
      endPoint: {
        x: 720, // 结束点的 x 坐标
        y: 140 + index * 80, // 结束点的 y 坐标
      },
    });
  });

  // 每个敏感字节点到每个目标服务节点中的具体 API 的连接
  input.sensitiveWords.forEach((word, tagIndex) => {
    const wordIds = word.id.split(",").map((id) => id.trim());

    let currentY = 190; // 初始 y 坐标

    input.source.forEach((service, sourceIndex) => {
      service.api.forEach((api, apiIndex) => {
        if (wordIds.includes(api.id)) {
          const centerY = currentY + apiIndex * 45; // 每个 API 增加 45 高度

          edges.push({
            id: `tag-${tagIndex}-source-${sourceIndex}-${apiIndex}`,
            sourceNodeId: `tag-${tagIndex}`,
            targetNodeId: `source-${sourceIndex}`,
            type: "ServerLine", // 连接线类型为直线
            startPoint: {
              x: 840, // 起始点的 x 坐标
              y: 140 + tagIndex * 80, // 起始点的 y 坐标
            },
            endPoint: {
              x: 1049, // 结束点的 x 坐标
              y: centerY, // 结束点的 y 坐标
            },
            properties: {
              id: api.id, // 带上具体的 API 的 id
            },
          });
        }
      });

      // 更新 currentY，加上当前服务节点的高度和空隙
      const apiCount = service.api.length;
      const height = 180 + (apiCount - 1) * 45; // 每个 API 增加 45 高度
      currentY += height + 30; // 每个服务节点之间增加 205 高度
    });
  });

  return edges;
}
</script>

<style scoped>
.modal {
  position: absolute;
  top: 0;
  left: 0;
  width: 440px;
  height: 338px;
  transform: translate(-66%, 10%);
}
</style>
